/*
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

 You should have received a copy of the GNU  General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "Device.h"

// Base class for  devices
//! \todo Verify pins - analog and pwm
//! \todo Verify pin isnt used for 2 devices or device and I2c,etc.
Device::Device() {}

//bool Device::wireInitialized = 0;

//! Read data for simple analog or digital sensor
int16_t Device::read()
{ 
    if (deviceType == DIGITAL_SENSOR) return( digitalRead(_pin) );
    if (deviceType == ANALOG_SENSOR)  return( analogRead(_pin) );
    else return(errorCode = ERROR_UNSUPPORTED);  // Need to override read method for other devices
}

//! \param devAddress - pin of the device
//! \param devType - device type (ANALOG_DEVICE, etc.)  see Device.h for list
//! \return ErrorCode

//! Initialize
int16_t Device::begin(int devAddress, DeviceType devType)
{
    metric = true;
    _pin = devAddress;
    deviceType = devType;



    switch (deviceType)
    {
    case DIGITAL_SENSOR:
        pinMode(_pin, INPUT);
        DBGLN("** Digital Sensor");
        break;
    case ANALOG_SENSOR:
        pinMode(_pin, INPUT);
        DBGLN("** Analog Sensor");
        break;
    case DIGITAL_OUT_DEVICE:
    case PWM_DEVICE:
        pinMode(_pin, OUTPUT);
        break;
    case I2C_DEVICE:
        _devAddress = devAddress;
        if (devAddress > 127)return(errorCode=ERROR_BAD_ADDRESS);
        break;
    }

    if (deviceType != I2C_DEVICE){
        DBG("     using pin=");
        DBGLN(_pin);
    }
    else
    {
        DBG("     using i2c addr=");
        DBGLN(_pin);
    }
    return(errorCode=SUCCESS);
}

//! Set whether to use Imperial or Metric (where applicable). Default is metric
void Device::setMetric(bool flag)
{
    metric = flag;
}

// UTILITY ROUTINES
float Device::centigradeToFarenheit(int centi) {
    return( ( (float) centi * 1.8) + 32.0 );
}

float Device::centimeterToInch(int centi) {
    return( (float) centi * 0.3937  );
}

// int numbers 0 (on digital pin 2) and 1 (on digital pin 3).
// The Arduino Mega has four additional: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19),
// and 5 (pin 18)
//! Map pin to hw interrupt number
int Device::pinToInterrupt(int pin)
{
    switch (pin)
    {
    case 2:  //
        return(0);
        break;
    case 3:  //
        return(1);
        break;
#if defined(__AVR_ATmega2560__)
    case 21:  // Mega Only
        return(2);
        break;
    case 20:  // Mega Only
        return(3);
        break;
    case 19:  // Mega Only
        return(4);
        break;
    case 18:  // Mega Only
        return(5);
        break;
#endif
    default:
        return(errorCode=ERROR_NOT_INTERRUPT_PIN);
        break;
    }
}
